package com.xspace.android.xafcommon.util;

import com.ctnq.base64.Base64Decoder;

import java.io.IOException;

/**
 * @version V1.0.0
 * @ClassName: Base64Img
 * @author:qbluo
 * @Date：2013-10-25
 * @Description: TODO
 */
public class Base64Utils {
    private static final String DEFAULT_ENCODING_TABLES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    private static String encodingTables = DEFAULT_ENCODING_TABLES;

    static {
        int offset = 0;
        int move = offset % DEFAULT_ENCODING_TABLES.length();
        encodingTables = DEFAULT_ENCODING_TABLES.substring(move)
                + DEFAULT_ENCODING_TABLES.substring(0, move);
    }

    /**
     * encode
     *
     * @param raw The byte array to encode
     * @return A string in base64 encoding
     */
    public static String encodex(byte[] raw) {
        StringBuffer encoded = new StringBuffer();
        for (int i = 0; i < raw.length; i += 3) {
            encoded.append(encodeBlock(raw, i));
        }
        return encoded.toString();
    }

    /**
     * encodeBlock
     * <p>
     * creates 4 base64 digits from three bytes of input data. we use an
     * integer, block, to hold the 24 bits of input data.
     *
     * @return An array of 4 characters
     */
    protected static char[] encodeBlock(byte[] raw, int offset) {
        int block = 0;
        // how much space left in input byte array
        int slack = raw.length - offset - 1;
        // if there are fewer than 3 bytes in this block, calculate end
        int end = (slack >= 2) ? 2 : slack;
        // convert signed quantities into unsigned
        for (int i = 0; i <= end; i++) {
            byte b = raw[offset + i];
            int neuter = (b < 0) ? b + 256 : b;
            block += neuter << (8 * (2 - i));
        }
        // extract the base64 digets, which are six bit quantities.
        char[] base64 = new char[4];
        for (int i = 0; i < 4; i++) {
            int sixbit = (block >>> (6 * (3 - i))) & 0x3f;
            base64[i] = getChar(sixbit);
        }
        // pad return block if needed
        if (slack < 1)
            base64[2] = '=';
        if (slack < 2)
            base64[3] = '=';
        // always returns an array of 4 characters
        return base64;
    }

    /**
     * decode
     * <p>
     * convert a base64 string into an array of bytes.
     *
     * @param base64 A String of base64 digits to decode.
     * @return A byte array containing the decoded value of the base64 input
     * string
     */
    public static byte[] decodex(String base64) {
        // how many padding digits?
        int pad = 0;
        for (int i = base64.length() - 1; base64.charAt(i) == '='; i--)
            pad++;
        // we know know the lenght of the target byte array.
        int length = base64.length() * 6 / 8 - pad;
        byte[] raw = new byte[length];
        int rawIndex = 0;
        // loop through the base64 value. A correctly formed
        // base64 string always has a multiple of 4 characters.
        for (int i = 0; i < base64.length(); i += 4) {
            int block = (getValue(base64.charAt(i)) << 18)
                    + (getValue(base64.charAt(i + 1)) << 12)
                    + (getValue(base64.charAt(i + 2)) << 6)
                    + (getValue(base64.charAt(i + 3)));
            // based on the block, the byte array is filled with the
            // appropriate 8 bit values
            for (int j = 0; j < 3 && rawIndex + j < raw.length; j++)
                raw[rawIndex + j] = (byte) ((block >> (8 * (2 - j))) & 0xff);
            rawIndex += 3;
        }
        return raw;
    }

    /**
     * getChar
     * <p>
     * encapsulates the translation from six bit quantity to base64 digit
     */
    protected static char getChar(int sixBit) {
        return encodingTables.charAt(sixBit);
    }

    /**
     * getValue
     * <p>
     * translates from base64 digits to their 6 bit value
     */
    protected static int getValue(char c) {
        if (c == '=')
            return 0;
        return encodingTables.indexOf(c);
    }

    public static void main(String[] args) throws IOException {
//		String data = "abcd你好";
//		String result = Base64Utils.encodex(data.getBytes("utf-8"));
//		System.out.println(data);
//		System.out.println(new String(result));
//		System.out.println(new String(Base64Utils.decodex("/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a\n" +
//				"                                                                         HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy\n" +
//				"                                                                         MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8ADIDASIA\n" +
//				"                                                                         AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA\n" +
//				"                                                                         AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3\n" +
//				"                                                                         ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm\n" +
//				"                                                                         p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA\n" +
//				"                                                                         AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx\n" +
//				"                                                                         BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK\n" +
//				"                                                                         U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3\n" +
//				"                                                                         uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0T4j/\n" +
//				"                                                                         ABEh8GWiWtsiz6tcruijP3Y1zje345wO+PauV8P+IdUuYVuNdnvHuZPmITUZIFX0ASNMfrXD/EWZ\n" +
//				"                                                                         7n4w3izNuVJ4Y1B6BQi8fz/OumR65MVXlSso9TOpNxtY7Ma9Aehuv/BrP/8AEVKmsQOM+ZcL7HVL\n" +
//				"                                                                         j/4iuPSSrCSV56xEv6Rkps6ltSVyAk12D6x6rJn/AMfQCtDS/Ek1veR2l/KZYZCFSaRAkkZPADgc\n" +
//				"                                                                         FSeAw79etccklSy/6VZyWzHqp8s/3Wx/WtYV5J3KUmetUVV0yZ7jSrOeQ5eSBHY+5UE0V6y1Nz5o\n" +
//				"                                                                         8ff8li1D/r6i/wDQErqrC2a/1C3sxMkJmcLvfoK5bx9/yWLUP+vqL/0Ba3A/TnkVwY3eNzCt0NS+\n" +
//				"                                                                         srnSNRlsbsYkQ8MOjDsR7VG9x5aZ79q6YOvjLw+EY/8AE6sF+Vu8yf4/1+tU/DOmxRebrmrqUs7P\n" +
//				"                                                                         lEYcySDoMH3/AF/GuV0LyXLszLl102Kd/pl9o0FjPdzJvugW+z5+ZBx1H41JDL84qlf6lPrGqS39\n" +
//				"                                                                         yfmY/ImeEXsBSxS/OKzm48/u7Amr6Hr+iHOgacf+nWL/ANBFFJoX/Ivab/16xf8AoAor3FsdiPm/\n" +
//				"                                                                         x/8A8lh1D/r5j/8AQFrTV8msz4gf8lg1D/r4j/8AQFq2smD1rjxavYyq9Do9FTU7e9gvLK3nfa+N\n" +
//				"                                                                         yRkqR3BPpXR+NG1K9uoreG3nktEXf+7jLAtz1I9B/OuP0/VryJkjhuZokDA7VkIXr6VveKdVuoNT\n" +
//				"                                                                         2wXcyII1yschUZ59Kwi0qTWvQyXwtGEr44IwRxipUkwazTMWbOeaekzZxmuVwIse8aD/AMi9pn/X\n" +
//				"                                                                         pF/6AKKNB/5F3TP+vSL/ANAFFe6tjtPCPi7oculfEKHWSp+x32xt4HCuoCsP0B/GsgPX0fq+jafr\n" +
//				"                                                                         2nvY6lbJPbvztbqD6g9jXhvijQLTQ9WNnavM0akgGRgTgfhXPiI3SZnUWhjxzmNtympHuWk4OAPQ\n" +
//				"                                                                         VGLdfVqd5C+rVxNIxshRJVvTrW41K+htLVC80rbEHue59h1PsDVSOJTcRockMwBr3Twt4Z0zRLOO\n" +
//				"                                                                         4to2a4lQFppDlgDzgcAAf5Oa0p0udlRjzM3LS3S0s4LaPJSGNY1z6AYoqaivSOg//9k="), "utf-8"));
        System.out.println(new String(Base64Decoder.decodeToBytes("/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a\n" +
                "                                                                         HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy\n" +
                "                                                                         MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8ADIDASIA\n" +
                "                                                                         AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA\n" +
                "                                                                         AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3\n" +
                "                                                                         ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm\n" +
                "                                                                         p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA\n" +
                "                                                                         AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx\n" +
                "                                                                         BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK\n" +
                "                                                                         U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3\n" +
                "                                                                         uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0T4j/\n" +
                "                                                                         ABEh8GWiWtsiz6tcruijP3Y1zje345wO+PauV8P+IdUuYVuNdnvHuZPmITUZIFX0ASNMfrXD/EWZ\n" +
                "                                                                         7n4w3izNuVJ4Y1B6BQi8fz/OumR65MVXlSso9TOpNxtY7Ma9Aehuv/BrP/8AEVKmsQOM+ZcL7HVL\n" +
                "                                                                         j/4iuPSSrCSV56xEv6Rkps6ltSVyAk12D6x6rJn/AMfQCtDS/Ek1veR2l/KZYZCFSaRAkkZPADgc\n" +
                "                                                                         FSeAw79etccklSy/6VZyWzHqp8s/3Wx/WtYV5J3KUmetUVV0yZ7jSrOeQ5eSBHY+5UE0V6y1Nz5o\n" +
                "                                                                         8ff8li1D/r6i/wDQErqrC2a/1C3sxMkJmcLvfoK5bx9/yWLUP+vqL/0Ba3A/TnkVwY3eNzCt0NS+\n" +
                "                                                                         srnSNRlsbsYkQ8MOjDsR7VG9x5aZ79q6YOvjLw+EY/8AE6sF+Vu8yf4/1+tU/DOmxRebrmrqUs7P\n" +
                "                                                                         lEYcySDoMH3/AF/GuV0LyXLszLl102Kd/pl9o0FjPdzJvugW+z5+ZBx1H41JDL84qlf6lPrGqS39\n" +
                "                                                                         yfmY/ImeEXsBSxS/OKzm48/u7Amr6Hr+iHOgacf+nWL/ANBFFJoX/Ivab/16xf8AoAor3FsdiPm/\n" +
                "                                                                         x/8A8lh1D/r5j/8AQFrTV8msz4gf8lg1D/r4j/8AQFq2smD1rjxavYyq9Do9FTU7e9gvLK3nfa+N\n" +
                "                                                                         yRkqR3BPpXR+NG1K9uoreG3nktEXf+7jLAtz1I9B/OuP0/VryJkjhuZokDA7VkIXr6VveKdVuoNT\n" +
                "                                                                         2wXcyII1yschUZ59Kwi0qTWvQyXwtGEr44IwRxipUkwazTMWbOeaekzZxmuVwIse8aD/AMi9pn/X\n" +
                "                                                                         pF/6AKKNB/5F3TP+vSL/ANAFFe6tjtPCPi7oculfEKHWSp+x32xt4HCuoCsP0B/GsgPX0fq+jafr\n" +
                "                                                                         2nvY6lbJPbvztbqD6g9jXhvijQLTQ9WNnavM0akgGRgTgfhXPiI3SZnUWhjxzmNtympHuWk4OAPQ\n" +
                "                                                                         VGLdfVqd5C+rVxNIxshRJVvTrW41K+htLVC80rbEHue59h1PsDVSOJTcRockMwBr3Twt4Z0zRLOO\n" +
                "                                                                         4to2a4lQFppDlgDzgcAAf5Oa0p0udlRjzM3LS3S0s4LaPJSGNY1z6AYoqaivSOg//9k="), "utf-8"));
        // aYLlbQU/qQYnxS==
    }
}
